/**
 * 
 */
package com.doone.telmarket.infrastructure.xmlbeans;

import java.io.Serializable;
import java.util.Date;

import noNamespace.MessageDocument;
import noNamespace.RootDocument;
import noNamespace.FormDocument.Form;
import noNamespace.HeadDocument.Head;
import noNamespace.MessageDocument.Message;
import noNamespace.PHONEPACKAGEQUERYDocument.PHONEPACKAGEQUERY;
import noNamespace.RootDocument.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.xmlbeans.XmlException;
import org.springframework.stereotype.Repository;

import com.doone.telmarket.vo.ServiceOrderRelationResult;
import com.doone.telmarket.vo.ServiceOrderResult;

/**
 * @author 吴同庆
 * @date 2009-10-21
 * @description
 * @package com.doone.telmarket.infrastructure.xmlbeans
 */
@Repository
public class MessageBodyFactory implements Serializable {

	private final static String CONNECT_TYPE = "connectType";
	private final static String CONNECT_TYPE_VALUE = "66";
	private final static String OBJECT_NUM = "objectNum";
	private final static String OBJECT_TYPE = "objectType";
	private final static String OBJECT_TYPE_VALUE = "50";
	private final static String CITY_CODE = "cityCode";
	private final static String ORDER_TYPE_ID = "orderTypeId";
	private final static String ORDER_TYPE_ID_VALUE = "005";
	private final static String ACTION = "action";
	private final static String PARAM_1 = "param1";
	private final static String PARAM_2 = "param2";
	private final static String XML_PREFIX = "<?xml version=\"1.0\" encoding=\"GBK\"?>";
	private final static String MESSAGE_PREFIX = "MESSAGEID";
	private final static String DEFAULT_HEAD_VALUE = "";
	private final static String DEFAULT_MESSAGE_LENGTH = "807";
	private final static String DEFAULT_MESSAGE_PRIORITY = "N";
	private final static String DEFAULT_MESSAGE_ENCODING = "xml/form";
	private final static String DEFAULT_TIME_OUT = "0";
	private final static String DEFULT_FORM_TYPE_VALUE = "string";

	private final static String ORDER_ACTION = "01";
	private final static String QUIT_ORDER_ACTION = "02";

	private final static String RESULT_CODE = "resultCode";
	private final static String EFFECTIVE_TIME = "EFFECTIVETIME";
	private final static String MESSAGE = "message";
	private final static String EXPIRE_TIME = "EXPIRETIME";

	public final static String LOAD_XML_EXCEPTION = "订购、退订解析返回的xml result出错";
	public final static String RELATION_XML_EXCEPTION = "订购关系查询返回的xml result出错";

	private final static String QUERY_TYPE = "QUERYTYPE";
	private final static String QUERY_ORDER_RELATION = "1";
	private final static String START_TIME = "STARTTIME";
	private final static String END_TIME = "ENDTIME";

	private static final long serialVersionUID = 4964074521006973126L;

	public String orderMessage(String cityCode, String accNbr, String productId, String serviceOrderMode) {
		return removeCDATA(createBusinessHandingMessageBody(cityCode, accNbr, productId, serviceOrderMode, ORDER_ACTION));
	}

	public String quitOrderMessage(String cityCode, String accNbr, String productId, String serviceOrderMode) {
		return removeCDATA(createBusinessHandingMessageBody(cityCode, accNbr, productId, serviceOrderMode,
				QUIT_ORDER_ACTION));
	}

	public String orderRelationMessage(String cityCode, String accNbr, String serviceOrderMode) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(XML_PREFIX);
		MessageDocument messageDocument = MessageDocument.Factory.newInstance();
		Message message = messageDocument.addNewMessage();
		createHead(message);
		message.setBody(createBusinessOrderRelationBody(cityCode, accNbr, serviceOrderMode));
		buffer.append(messageDocument.xmlText());
		return removeCDATA(buffer.toString());
	}

	String createBusinessHandingMessageBody(String cityCode, String accNbr, String productId, String serviceOrderMode,
			String action) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(XML_PREFIX);
		MessageDocument messageDocument = MessageDocument.Factory.newInstance();
		Message message = messageDocument.addNewMessage();
		createHead(message);
		message.setBody(createBusinessHandlingBody(cityCode, accNbr, productId, serviceOrderMode, action));
		buffer.append(messageDocument.xmlText());
		return buffer.toString();
	}

	String createBusinessHandlingBody(String cityCode, String accNbr, String productId, String serviceOrderMode,
			String action) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(XML_PREFIX);
		RootDocument rootDocument = RootDocument.Factory.newInstance();
		rootDocument.addNewRoot();
		Root root = rootDocument.getRoot();
		addForm(root, CONNECT_TYPE, CONNECT_TYPE_VALUE);
		addForm(root, CITY_CODE, cityCode);
		addForm(root, OBJECT_TYPE, OBJECT_TYPE_VALUE);
		addForm(root, OBJECT_NUM, accNbr);
		addForm(root, ORDER_TYPE_ID, ORDER_TYPE_ID_VALUE);
		addForm(root, ACTION, action);
		addForm(root, PARAM_1, productId);
		addForm(root, PARAM_2, serviceOrderMode);
		buffer.append(rootDocument.xmlText());
		return buffer.toString();
	}

	String createBusinessOrderRelationBody(String cityCode, String accNbr, String serviceOrderMode) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(XML_PREFIX);
		RootDocument rootDocument = RootDocument.Factory.newInstance();
		rootDocument.addNewRoot();
		Root root = rootDocument.getRoot();
		addForm(root, CONNECT_TYPE, CONNECT_TYPE_VALUE);
		addForm(root, CITY_CODE, cityCode);
		addForm(root, OBJECT_TYPE, OBJECT_TYPE_VALUE);
		addForm(root, OBJECT_NUM, accNbr);
		addForm(root, QUERY_TYPE, QUERY_ORDER_RELATION);
		addForm(root, PARAM_1, serviceOrderMode);
		addForm(root, START_TIME, DEFAULT_HEAD_VALUE);
		addForm(root, END_TIME, DEFAULT_HEAD_VALUE);
		buffer.append(rootDocument.xmlText());
		return buffer.toString();
	}

	void createHead(Message message) {
		message.addNewHead();
		Head head = message.getHead();
		head.setMid(generateMessageId());
		head.setMtype(DEFAULT_HEAD_VALUE);
		head.setMto(DEFAULT_HEAD_VALUE);
		head.setMlength(DEFAULT_MESSAGE_LENGTH);
		head.setMpriority(DEFAULT_MESSAGE_PRIORITY);
		head.setMencoding(DEFAULT_MESSAGE_ENCODING);
		head.setValidityid(DEFAULT_HEAD_VALUE);
		head.setTimeout(DEFAULT_TIME_OUT);
		head.setService(DEFAULT_HEAD_VALUE);
	}

	String generateMessageId() {
		StringBuffer buffer = new StringBuffer();
		buffer.append(MESSAGE_PREFIX);
		buffer.append(new Date().getTime());
		return buffer.toString();
	}

	void addForm(Root root, String name, String value) {
		Form form = root.addNewForm();
		form.setName(name);
		form.setValue(value);
		form.setType(DEFULT_FORM_TYPE_VALUE);
	}

	Root createResult(String xml) throws XmlException {
		RootDocument rootDocument = RootDocument.Factory.parse(xml);
		return rootDocument.getRoot();
	}

	public ServiceOrderResult createServiceOrderResult(String xml) {
		Root root;
		try {
			root = createResult(xml);
		} catch (XmlException e) {
			throw new RuntimeException(LOAD_XML_EXCEPTION);
		}
		Form[] forms = root.getFormArray();
		String resultCode = "";
		String effectiveTime = "";
		String message = "";
		String expireTime = "";
		for (Form form : forms) {
			if (form.getName().equalsIgnoreCase(RESULT_CODE)) {
				resultCode = form.getValue();
			}
			if (form.getName().equalsIgnoreCase(EFFECTIVE_TIME)) {
				effectiveTime = form.getValue();
			}
			if (form.getName().equalsIgnoreCase(MESSAGE)) {
				message = form.getValue();
			}
			if (form.getName().equalsIgnoreCase(EXPIRE_TIME)) {
				expireTime = form.getValue();
			}
		}
		return new ServiceOrderResult(resultCode, message, effectiveTime, expireTime);
	}

	public String removeCDATA(String sourceString) {
		return StringUtils.remove(StringUtils.remove(sourceString, "<![CDATA["), "]]>");
	}

	public ServiceOrderRelationResult createServiceOrderRelationResult(String xml) {
		Root root;
		try {
			root = createResult(xml);
			Form[] forms = root.getFormArray();
			String resultCode = "";
			String message = "";
			String ismpListXml = "";
			for (Form form : forms) {
				if (form.getName().equalsIgnoreCase(RESULT_CODE)) {
					resultCode = form.getValue();
				}
				if (form.getName().equalsIgnoreCase(MESSAGE)) {
					message = form.getValue();
				}
				if (form.getName().equalsIgnoreCase("ismplist")) {
					;
				}
				ismpListXml = form.getValue();
			}
			ServiceOrderRelationResult result = new ServiceOrderRelationResult(resultCode, message);
			if (!ismpListXml.equals("")) {
				Root productRoot;
				productRoot = createResult(ismpListXml);
				PHONEPACKAGEQUERY[] phones = productRoot.getPHONEPACKAGEQUERYArray();
				for (PHONEPACKAGEQUERY phonepackagequery : phones) {
					result.addProductId(phonepackagequery.getID());
				}
			}
			return result;
		} catch (XmlException e) {
			e.printStackTrace();
		}
		return null;
	}

}
